/*
 *  Same as test-dev-mandel2.js, but mandelbrot is implemented as a function
 *  which generates more efficient code.  Odd comparison idioms haven't been
 *  fixed (which were due to missing mechanisms at the time).
 */

/*---
{
    "slow": true
}
---*/

/* Computed with Rhino, verified against V8 */

/*===
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
........................................#.......................................
................................................................................
....................................####........................................
....................................####........................................
..............................#..##########.....................................
..............................#################.................................
............................###################.................................
...........................#####################................................
.................#######..######################................................
................#########.######################................................
.#############################################..................................
................#########.######################................................
.................#######..######################................................
...........................#####################................................
............................###################.................................
..............................#################.................................
..............................#..##########.....................................
....................................####........................................
....................................####........................................
................................................................................
........................................#.......................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
===*/

function mandel() {
    var w = 80;
    var h = 40;
    var iter = 100;
    var i, j, k;
    var x0, y0, xx, yy, c, xx2, yy2;
    var res;

    for (i = 0; i - h; i += 1) {
        y0 = (i / h) * 4.0 - 2.0;

        res = [];

        for (j = 0; j - w; j += 1) {
            x0 = (j / w) * 4.0 - 2.0;

            xx = 0;
            yy = 0;
            c = "#";

            for (k = 0; k - iter; k += 1) {
                /* z -> z^2 + c
                 *   -> (xx+i*yy)^2 + (x0+i*y0)
                 *   -> xx*xx+i*2*xx*yy-yy*yy + x0 + i*y0
                 *   -> (xx*xx - yy*yy + x0) + i*(2*xx*yy + y0)
                 */

                xx2 = xx*xx;
                yy2 = yy*yy;

                if (Math.max(0, 4.0 - (xx2 + yy2))) {
                    yy = 2*xx*yy + y0;
                    xx = xx2 - yy2 + x0;
                } else {
                    /* xx^2 + yy^2 >= 4.0 */
                    c = ".";
                    break;
                }
            }

            res[res.length] = c;
        }

        print(res.join(''));
    }
}

try {
    mandel();
} catch (e) {
    print(e);
}
